import { _decorator, Component, EventKeyboard, Input, input, KeyCode } from 'cc';
import { EventName } from '../consts/events';
import { EventManager } from '../utils/events/events';
const { ccclass } = _decorator;

const DirectionBit = {
    Left: 1 << 0,
    Right: 1 << 1,
    Up: 1 << 2,
    Down: 1 << 3
};

@ccclass('Keyboard')
export class Keyboard extends Component {
    protected onLoad(): void {
        input.on(Input.EventType.KEY_DOWN, this.OnKeyDown, this);
        input.on(Input.EventType.KEY_UP, this.OnKeyUp, this);
    }

    protected onDestroy(): void {
        input.off(Input.EventType.KEY_DOWN, this.OnKeyDown, this);
        input.off(Input.EventType.KEY_UP, this.OnKeyUp, this);
    }

    private KeyStatus = 0;
    private OnKeyDown(event: EventKeyboard): void {
        switch (event.keyCode) {
            case KeyCode.KEY_W:
                EventManager.instance.emitEvent(EventName.MoveUp);
                this.KeyStatus = this.KeyStatus | DirectionBit.Up;
                break;
            case KeyCode.KEY_S:
                EventManager.instance.emitEvent(EventName.MoveDown);
                this.KeyStatus = this.KeyStatus | DirectionBit.Down;
                break;
            case KeyCode.KEY_A:
                EventManager.instance.emitEvent(EventName.MoveLeft);
                this.KeyStatus = this.KeyStatus | DirectionBit.Left;
                break;
            case KeyCode.KEY_D:
                EventManager.instance.emitEvent(EventName.MoveRight);
                this.KeyStatus = this.KeyStatus | DirectionBit.Right;
                break;
            case KeyCode.SPACE:
                EventManager.instance.emitEvent(EventName.PlayerShoot);
                break;
        }
    }

    private OnKeyUp(event: EventKeyboard): void {
        switch (event.keyCode) {
            case KeyCode.KEY_W:
                this.KeyStatus = this.KeyStatus & ~DirectionBit.Up;
                this.updateKeyStatus();
                break;
            case KeyCode.KEY_S:
                this.KeyStatus = this.KeyStatus & ~DirectionBit.Down;
                this.updateKeyStatus();
                break;
            case KeyCode.KEY_A:
                this.KeyStatus = this.KeyStatus & ~DirectionBit.Left;
                this.updateKeyStatus();
                break;
            case KeyCode.KEY_D:
                this.KeyStatus = this.KeyStatus & ~DirectionBit.Right;
                this.updateKeyStatus();
                break;
        }
    }

    private updateKeyStatus() {
        if (this.KeyStatus & DirectionBit.Left) {
            EventManager.instance.emitEvent(EventName.MoveLeft);
        } else if (this.KeyStatus & DirectionBit.Right) {
            EventManager.instance.emitEvent(EventName.MoveRight);
        } else if (this.KeyStatus & DirectionBit.Up) {
            EventManager.instance.emitEvent(EventName.MoveUp);
        } else if (this.KeyStatus & DirectionBit.Down) {
            EventManager.instance.emitEvent(EventName.MoveDown);
        } else if (this.KeyStatus === 0) {
            EventManager.instance.emitEvent(EventName.MoveStop);
        }
    }
}
